package com.kds.smarthome.controller;

import com.alibaba.excel.EasyExcel;
import com.kds.smarthome.annotation.BuildingCode;
import com.kds.smarthome.common.AjaxResponse;
import com.kds.smarthome.controller.vo.FunctionImportVO;
import com.kds.smarthome.controller.vo.FunctionQueryVO;
import com.kds.smarthome.entity.Building;
import com.kds.smarthome.entity.Function;
import com.kds.smarthome.excel.FunctionImportListener;
import com.kds.smarthome.security.jwt.TokenProvider;
import com.kds.smarthome.service.FunctionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/function")
public class FunctionController {

    @Autowired
    private FunctionService functionService;

    @Autowired
    private TokenProvider tokenProvider;

    @GetMapping("/query")
    public AjaxResponse<List<Map<String, String>>> getFunctionsByBuilding(
            @BuildingCode String buildingCode,
            @RequestHeader("Authorization") String token) {

        try {
            Building currentBuilding = tokenProvider.getCurrentBuilding(token, buildingCode);
            if (currentBuilding == null) {
                return AjaxResponse.error("未找到指定建筑");
            }

            log.debug("Query functions for building: {}", buildingCode);

            List<Map<String, String>> functions = functionService.findAccumulateFunctions(buildingCode);

            return AjaxResponse.success(functions);
        } catch (RuntimeException e) {
            log.error("Error querying functions", e);
            return AjaxResponse.error(e.getMessage());
        }
    }

    /**
     * 获取所有功能点
     */
    @GetMapping
    public AjaxResponse<List<Function>> getAllFunctions() {
        try {
            List<Function> functions = functionService.findAll();
            return AjaxResponse.success(functions);
        } catch (Exception e) {
            log.error("获取功能点列表失败", e);
            return AjaxResponse.error("获取功能点列表失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID获取功能点
     */
    @GetMapping("/{tid}")
    public AjaxResponse<Function> getFunctionById(@PathVariable Integer tid) {
        try {
            Function function = functionService.findById(tid);
            if (function == null) {
                return AjaxResponse.error("未找到指定功能点");
            }
            return AjaxResponse.success(function);
        } catch (Exception e) {
            log.error("获取功能点详情失败", e);
            return AjaxResponse.error("获取功能点详情失败：" + e.getMessage());
        }
    }

    /**
     * 根据FID获取功能点
     */
    @GetMapping("/fid/{fid}")
    public AjaxResponse<Function> getFunctionByFid(@PathVariable String fid) {
        try {
            Function function = functionService.findByFid(fid);
            if (function == null) {
                return AjaxResponse.error("未找到指定功能点");
            }
            return AjaxResponse.success(function);
        } catch (Exception e) {
            log.error("获取功能点详情失败", e);
            return AjaxResponse.error("获取功能点详情失败：" + e.getMessage());
        }
    }

    /**
     * 根据建筑编码获取功能点列表
     */
    @GetMapping("/building/{buildingCode}")
    public AjaxResponse<List<Function>> getFunctionsByBuildingCode(@PathVariable String buildingCode) {
        try {
            List<Function> functions = functionService.findByBuildingCode(buildingCode);
            return AjaxResponse.success(functions);
        } catch (Exception e) {
            log.error("获取建筑功能点列表失败", e);
            return AjaxResponse.error("获取建筑功能点列表失败：" + e.getMessage());
        }
    }

    /**
     * 创建功能点
     */
    @PostMapping
    public AjaxResponse<?> createFunction(@RequestBody Function function) {
        try {
            functionService.create(function);
            return AjaxResponse.success("创建功能点成功");
        } catch (Exception e) {
            log.error("创建功能点失败", e);
            return AjaxResponse.error("创建功能点失败：" + e.getMessage());
        }
    }

    /**
     * 更新功能点
     */
    @PutMapping("/{tid}")
    public AjaxResponse<?> updateFunction(@PathVariable Integer tid, @RequestBody Function function) {
        try {
            function.setTid(tid);
            functionService.update(function);
            return AjaxResponse.success("更新功能点成功");
        } catch (Exception e) {
            log.error("更新功能点失败", e);
            return AjaxResponse.error("更新功能点失败：" + e.getMessage());
        }
    }

    /**
     * 删除功能点
     */
    @DeleteMapping("/{tid}")
    public AjaxResponse<?> deleteFunction(@PathVariable Integer tid) {
        try {
            functionService.delete(tid);
            return AjaxResponse.success("删除功能点成功");
        } catch (Exception e) {
            log.error("删除功能点失败", e);
            return AjaxResponse.error("删除功能点失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除功能点
     */
    @DeleteMapping("/batch")
    public AjaxResponse<?> batchDeleteFunctions(@RequestBody List<Integer> tids) {
        try {
            functionService.batchDelete(tids);
            return AjaxResponse.success("批量删除功能点成功");
        } catch (Exception e) {
            log.error("批量删除功能点失败", e);
            return AjaxResponse.error("批量删除功能点失败：" + e.getMessage());
        }
    }

    /**
     * 条件查询功能点
     */
    @PostMapping("/search")
    public AjaxResponse<List<Function>> searchFunctions(@RequestBody Function function) {
        try {
            List<Function> functions = functionService.findByCondition(function);
            return AjaxResponse.success(functions);
        } catch (Exception e) {
            log.error("查询功能点失败", e);
            return AjaxResponse.error("查询功能点失败：" + e.getMessage());
        }
    }

    /**
     * 获取功能点数量
     */
    @PostMapping("/count")
    public AjaxResponse<Long> countFunctions(@RequestBody Function function) {
        try {
            long count = functionService.count(function);
            return AjaxResponse.success(count);
        } catch (Exception e) {
            log.error("统计功能点数量失败", e);
            return AjaxResponse.error("统计功能点数量失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询功能点
     */
    @PostMapping("/page")
    public AjaxResponse<Map<String, Object>> getFunctionsByPage(@RequestBody FunctionQueryVO queryVO) {
        try {
            Function function = new Function();
            // 设置查询条件
            function.setName(queryVO.getName());
            function.setEnergyType(queryVO.getEnergyType());
            function.setStatisticsType(queryVO.getStatisticsType());
            function.setDisabled(queryVO.getDisabled());

            List<Function> functions = functionService.findByPage(
                function,
                queryVO.getPageNum(),
                queryVO.getPageSize()
            );
            long total = functionService.count(function);

            Map<String, Object> result = new HashMap<>();
            result.put("list", functions);
            result.put("total", total);
            result.put("pageNum", queryVO.getPageNum());
            result.put("pageSize", queryVO.getPageSize());

            return AjaxResponse.success(result);
        } catch (Exception e) {
            log.error("分页查询功能点失败", e);
            return AjaxResponse.error("分页查询功能点失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询功能点（带排序）
     */
    @PostMapping("/page/sort")
    public AjaxResponse<Map<String, Object>> getFunctionsByPageWithSort(@RequestBody FunctionQueryVO queryVO) {
        try {
            Function function = new Function();
            // 设置查询条件
            function.setBuildingCode(queryVO.getBuildingCode());
            function.setName(queryVO.getName());
            function.setEnergyType(queryVO.getEnergyType());
            function.setStatisticsType(queryVO.getStatisticsType());
            function.setDisabled(queryVO.getDisabled());

            List<Function> functions = functionService.findByPageWithSort(
                function,
                queryVO.getPageNum(),
                queryVO.getPageSize(),
                queryVO.getSortField(),
                queryVO.getSortOrder()
            );
            long total = functionService.count(function);

            Map<String, Object> result = new HashMap<>();
            result.put("list", functions);
            result.put("total", total);
            result.put("pageNum", queryVO.getPageNum());
            result.put("pageSize", queryVO.getPageSize());
            result.put("sortField", queryVO.getSortField());
            result.put("sortOrder", queryVO.getSortOrder());

            return AjaxResponse.success(result);
        } catch (Exception e) {
            log.error("分页查询功能点失败", e);
            return AjaxResponse.error("分页查询功能点失败：" + e.getMessage());
        }
    }

    /**
     * 导入功能点Excel
     */
    @PostMapping("/import")
    public AjaxResponse<Map<String, Object>> importFunction(@RequestParam("file") MultipartFile file) {
        try {
            if (file == null || file.isEmpty()) {
                return AjaxResponse.error("请选择要导入的Excel文件");
            }

            // 检查文件类型
            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
                return AjaxResponse.error("请上传Excel文件（.xlsx或.xls格式）");
            }

            // 创建监听器
            FunctionImportListener listener = new FunctionImportListener(functionService);

            // 读取Excel
            EasyExcel.read(file.getInputStream(), FunctionImportVO.class, listener).sheet().doRead();

            // 返回导入结果
            Map<String, Object> result = new HashMap<>();
            result.put("successCount", listener.getSuccessCount());
            result.put("failCount", listener.getFailCount());
            result.put("errorList", listener.getErrorList());

            // 如果有错误，返回警告信息
            if (listener.getFailCount() > 0) {
                return AjaxResponse.warning("部分数据导入失败，请查看错误详情", result);
            }

            return AjaxResponse.success(result);
        } catch (Exception e) {
            log.error("导入功能点Excel失败", e);
            return AjaxResponse.error("导入功能点Excel失败：" + e.getMessage());
        }
    }
}
